home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 428_02 / libsrc / hookints.asm < prev    next >
Encoding:
Assembly Source File  |  1994-03-13  |  8.6 KB  |  353 lines

  1. ;-----------------------------------------------------------------------;
  2. ; HOOKINTS.ASM                                ;
  3. ;                                    ;
  4. ; Pictor, Version 1.51, Copyright (c) 1992-94 SoftCircuits.        ;
  5. ; Redistributed by permission.                        ;
  6. ;-----------------------------------------------------------------------;
  7. %    .MODEL    memmodel,c
  8.  
  9.     EXTRN    atexit:PROC
  10.     EXTRN    messagebox:PROC,sprintf:PROC
  11.  
  12.     .DATA
  13.     IF    @CodeSize
  14.     EXTRN    _PL_helpfunc:FAR PTR
  15. old_helpfunc    DD    0
  16.     ELSE
  17.     EXTRN    _PL_helpfunc:NEAR PTR
  18. old_helpfunc    DW    0
  19.     ENDIF
  20.  
  21.     PUBLIC    _PL_breakflag
  22. _PL_breakflag    DW    0
  23.  
  24. installed_flag    DB    0        ;1 = handler is installed
  25. registered_flag    DB    0        ;1 = unhookints registered w/atexit
  26.  
  27.     IF    @DataSize        ;Pointer to COLORSTRUCT for
  28. error_colors    DD    0        ; messagebox()
  29.     ELSE
  30. error_colors    DW    0
  31.     ENDIF
  32.  
  33. MB_RETRYABORT    EQU    03h        ;messagebox() flags
  34. MAX_ERRORNUM    EQU    0Ch
  35. error_00h    DB    "Attempted to write to write-protected disk",0
  36. error_01h    DB    "Unknown unit (invalid drive number)",0
  37. error_02h    DB    "Drive not ready (no diskette or drive door is open)",0
  38. error_03h    DB    "Unknown command requested",0
  39. error_04h    DB    "Data error (CRC)",0
  40. error_05h    DB    "Length of requested structure invalid",0
  41. error_06h    DB    "Seek error (move to requested cylinder failed)",0
  42. error_07h    DB    "Non-MS-DOS disk",0
  43. error_08h    DB    "Sector not found",0
  44. error_09h    DB    "Printer out of paper",0
  45. error_0Ah    DB    "Write fault",0
  46. error_0Bh    DB    "Read fault",0
  47. error_0Ch    DB    "General fault",0
  48.  
  49. error_table    LABEL    WORD
  50.     DW    OFFSET error_00h,OFFSET error_01h,OFFSET error_02h
  51.     DW    OFFSET error_03h,OFFSET error_04h,OFFSET error_05h
  52.     DW    OFFSET error_06h,OFFSET error_07h,OFFSET error_08h
  53.     DW    OFFSET error_09h,OFFSET error_0Ah,OFFSET error_0Bh
  54.     DW    OFFSET error_0Ch
  55.  
  56. error_format    DB    "%s",0Ah,"%s",0
  57. error_title    DB    "Error",0
  58. device_error    DB    "Device error",0
  59. disk_error    DB    "Error on drive "
  60. drive        DB    "A:",0
  61. buffer        DB    128 DUP (?)
  62.  
  63. old1B_handler    DD    0        ;Storage for old interrupt handlers
  64. old23_handler    DD    0
  65. old24_handler    DD    0
  66.  
  67.  
  68.     .CODE
  69. ;-----------------------------------------------------------------------;
  70. ; Ctrl-break interrupt hander.                        ;
  71. ;                                    ;
  72. ; Usage:    This procedure cannot be called directly from C.    ;
  73. ;-----------------------------------------------------------------------;
  74. IFDEF    ??version            ;Turbo Assembler
  75. int1B_handler    PROC    FAR
  76. ELSE
  77. int1B_handler    PROC FAR PRIVATE
  78. ENDIF
  79.     sti
  80.     push    ax
  81.     push    es
  82.     mov    ax,0040h
  83.     mov    es,ax
  84.     and    BYTE PTR es:[0071h],NOT 80h
  85.     mov    ax,@Data
  86.     mov    es,ax
  87.     mov    es:_PL_breakflag,1    ;Set break flag
  88.     pop    es
  89.     pop    ax
  90.     iret
  91. int1B_handler    ENDP
  92.  
  93. ;-----------------------------------------------------------------------;
  94. ; Ctrl-C interrupt handler.                        ;
  95. ;                                    ;
  96. ; Usage:    This procedure cannot be called directly from C.    ;
  97. ;-----------------------------------------------------------------------;
  98. IFDEF    ??version            ;Turbo Assembler
  99. int23_handler    PROC    FAR
  100. ELSE
  101. int23_handler    PROC FAR PRIVATE
  102. ENDIF
  103.     iret
  104. int23_handler    ENDP
  105.  
  106. ;-----------------------------------------------------------------------;
  107. ; This procedure becomes the new critical-error interrupt handler. This    ;
  108. ; handler disables help by setting int (*_PL_helpfunc)() to NULL. Help    ;
  109. ; must never be called from within an interrupt!            ;
  110. ;                                    ;
  111. ; Usage:    This procedure cannot be called directly from C.    ;
  112. ;-----------------------------------------------------------------------;
  113. IFDEF    ??version            ;Turbo Assembler
  114. int24_handler    PROC    FAR
  115. ELSE
  116. int24_handler    PROC FAR PRIVATE
  117. ENDIF
  118.     sti
  119.     push    bx
  120.     push    cx
  121.     push    dx
  122.     push    si
  123.     push    di
  124.     push    bp
  125.     push    ds
  126.     push    es
  127.     mov    dx,@Data        ;ds = data segment
  128.     mov    ds,dx
  129.     IF    @CodeSize
  130.     mov    bx,WORD PTR _PL_helpfunc[0]
  131.     mov    WORD PTR old_helpfunc[0],bx
  132.     mov    bx,WORD PTR _PL_helpfunc[2]
  133.     mov    WORD PTR old_helpfunc[2],bx
  134.     mov    WORD PTR _PL_helpfunc[0],0
  135.     mov    WORD PTR _PL_helpfunc[2],0
  136.     ELSE
  137.     mov    bx,_PL_helpfunc
  138.     mov    old_helpfunc,bx
  139.     mov    _PL_helpfunc,0
  140.     ENDIF
  141.     test    ah,80h            ;Was the error disk-related?
  142.     jnz    not_disk_error        ;No
  143.     add    al,'A'            ;Else set drive letter
  144.     mov    drive,al
  145.     mov    dx,OFFSET disk_error    ;Disk error message
  146.     jmp    err_type_ready
  147. not_disk_error:
  148.     mov    dx,OFFSET device_error    ;Device error message
  149. err_type_ready:
  150.     mov    bx,di            ;Error code
  151.     sub    bh,bh
  152.     cmp    bx,MAX_ERRORNUM
  153.     jna    good_errornum
  154.     mov    bx,MAX_ERRORNUM
  155. good_errornum:
  156.     shl    bx,1
  157.     add    bx,OFFSET error_table
  158.     mov    bx,[bx]
  159.     IF    @DataSize        ;sprintf(buffer,format,dx,bx);
  160.     push    ds
  161.     push    bx
  162.     push    ds
  163.     push    dx
  164.     push    ds
  165.     mov    ax,OFFSET error_format
  166.     push    ax
  167.     push    ds
  168.     mov    ax,OFFSET buffer
  169.     push    ax
  170.     ELSE
  171.     push    bx
  172.     push    dx
  173.     mov    ax,OFFSET error_format
  174.     push    ax
  175.     mov    ax,OFFSET buffer
  176.     push    ax
  177.     ENDIF
  178.     call    sprintf
  179.     IF    @DataSize
  180.     add    sp,16
  181.     ELSE
  182.     add    sp,8
  183.     ENDIF
  184.     IF    @DataSize        ;messagebox(msg,wtitle,flags,&colors);
  185.     push    WORD PTR error_colors[2]
  186.     push    WORD PTR error_colors[0]
  187.     mov    ax,MB_RETRYABORT
  188.     push    ax
  189.     push    ds
  190.     mov    ax,OFFSET error_title
  191.     push    ax
  192.     push    ds
  193.     mov    ax,OFFSET buffer
  194.     push    ax
  195.     ELSE
  196.     push    error_colors
  197.     mov    ax,MB_RETRYABORT
  198.     push    ax
  199.     mov    ax,OFFSET error_title
  200.     push    ax
  201.     mov    ax,OFFSET buffer
  202.     push    ax
  203.     ENDIF
  204.     call    messagebox
  205.     IF    @DataSize
  206.     add    sp,14
  207.     ELSE
  208.     add    sp,8
  209.     ENDIF
  210.     IF    @CodeSize
  211.     mov    bx,WORD PTR old_helpfunc[0]
  212.     mov    WORD PTR _PL_helpfunc[0],bx
  213.     mov    bx,WORD PTR old_helpfunc[2]
  214.     mov    WORD PTR _PL_helpfunc[2],bx
  215.     ELSE
  216.     mov    bx,old_helpfunc
  217.     mov    _PL_helpfunc,bx
  218.     ENDIF
  219.     cmp    ax,01h            ;Did user give 'retry' response?
  220.     je    end_int24_handler    ;Yes
  221.     mov    ax,03h            ;Else fail current system call
  222. end_int24_handler:
  223.     pop    es
  224.     pop    ds
  225.     pop    bp
  226.     pop    di
  227.     pop    si
  228.     pop    dx
  229.     pop    cx
  230.     pop    bx
  231.     iret
  232. int24_handler    ENDP
  233.  
  234.     PUBLIC    unhookints
  235. ;-----------------------------------------------------------------------;
  236. ; Removes the interrupt handlers installed by hookints and re-installs    ;
  237. ; the original interrupt vectors.                    ;
  238. ;                                    ;
  239. ; Usage:    int unhookints(void);                    ;
  240. ; Returns:    0 = success, -1 = error                    ;
  241. ;-----------------------------------------------------------------------;
  242. unhookints    PROC
  243.     mov    ax,-1            ;Return error if our handlers
  244.     cmp    installed_flag,0    ; are not installed
  245.     je    end_unhookints
  246.     push    ds            ;Preserve ds
  247.     push    ds            ;Use es to access data segment
  248.     pop    es
  249.     mov    ax,251Bh        ;Restore original interrupt 1Bh
  250.     lds    dx,es:old1B_handler    ; vector
  251.     int    21h
  252.     mov    ax,2523h        ;Restore original interrupt 23h
  253.     lds    dx,es:old23_handler    ; vector
  254.     int    21h
  255.     mov    ax,2524h        ;Restore original interrupt 24h
  256.     lds    dx,es:old24_handler    ; vector
  257.     int    21h
  258.     pop    ds
  259.     mov    installed_flag,0    ;Indicate we're no longer installed
  260.     sub    ax,ax
  261. end_unhookints:
  262.     ret
  263. unhookints    ENDP
  264.  
  265.     PUBLIC    hookints
  266. ;-----------------------------------------------------------------------;
  267. ; Installs custom interrupt handlers for Ctrl-C, Ctrl-break and        ;
  268. ; critical error interrupts, and registers unhookints with atexit.    ;
  269. ; colors argument specifies color used by messagebox for critical    ;
  270. ; errors.                                ;
  271. ;                                    ;
  272. ; Usage:    int hookints(COLORSTRUCT *colors);            ;
  273. ; Returns:    0 = success, -1 = error.                ;
  274. ;-----------------------------------------------------------------------;
  275. hookints    PROC colors:PTR BYTE
  276.     mov    ax,-1            ;Return error if we're already
  277.     cmp    installed_flag,1    ; installed
  278.     jne    not_installed
  279.     jmp    end_hookints
  280. not_installed:
  281.     IF    @DataSize
  282.     mov    ax,WORD PTR colors[0]
  283.     mov    WORD PTR error_colors[0],ax
  284.     mov    ax,WORD PTR colors[2]
  285.     mov    WORD PTR error_colors[2],ax
  286.     ELSE
  287.     mov    ax,colors
  288.     mov    error_colors,ax
  289.     ENDIF
  290.     mov    ax,351Bh        ;Get old interrupt 1Bh vector
  291.     int    21h
  292.     mov    WORD PTR old1B_handler[0],bx
  293.     mov    WORD PTR old1B_handler[2],es
  294.     push    ds            ;Set new interrupt 1Bh vector
  295.     mov    ax,251Bh
  296.     push    cs
  297.     pop    ds
  298.     mov    dx,OFFSET int1B_handler
  299.     int    21h
  300.     pop    ds
  301.     mov    ax,3523h        ;Get old interrupt 23h vector
  302.     int    21h
  303.     mov    WORD PTR old23_handler[0],bx
  304.     mov    WORD PTR old23_handler[2],es
  305.     push    ds            ;Set new interrupt 23h vector
  306.     mov    ax,2523h
  307.     push    cs
  308.     pop    ds
  309.     mov    dx,OFFSET int23_handler
  310.     int    21h
  311.     pop    ds
  312.     mov    ax,3524h        ;Get old interrupt 24h vector
  313.     int    21h
  314.     mov    WORD PTR old24_handler[0],bx
  315.     mov    WORD PTR old24_handler[2],es
  316.     push    ds            ;Set new interrupt 24h vector
  317.     mov    ax,2524h
  318.     push    cs
  319.     pop    ds
  320.     mov    dx,OFFSET int24_handler
  321.     int    21h
  322.     pop    ds
  323.     mov    installed_flag,1    ;Indicate we're installed
  324.     mov    ax,0
  325.     cmp    registered_flag,1    ;Are we already registered w/atexit?
  326.     je    end_hookints        ;Yes, done
  327.     mov    registered_flag,1
  328.     IF    @CodeSize        ;atexit(unhookints)
  329.     push    cs
  330.     mov    ax,OFFSET unhookints
  331.     push    ax
  332.     ELSE
  333.     mov    ax,OFFSET unhookints
  334.     push    ax
  335.     ENDIF
  336.     call    atexit
  337.     IF @CodeSize
  338.     add    sp,4
  339.     ELSE
  340.     inc    sp
  341.     inc    sp
  342.     ENDIF
  343.     or    ax,ax            ;Was atexit() successful?
  344.     jz    end_hookints        ;Yes, return 0
  345.     call    unhookints        ;Else uninstall handler
  346.     mov    registered_flag,0
  347.     mov    ax,-1            ;Return error
  348. end_hookints:
  349.     ret
  350. hookints    ENDP
  351.  
  352.     END
  353.